package com.ato.MyCollection.MapTest;

/**
 * @author wangjing
 * @create 2021--11--27--22:03
 * <p>
 * Map: 双列数据： key，value形式
 * HashMap : 作为Map的主要实现类：基本没有特殊要求都是这个   线程不安全的，效率高，可以存储null的key和null的value的  null:null
 * 注意，即使要用线程安全，也是用Collections 这个工具类里的，而不是HashTable
 * LinkedHashMap   和 Set 一样， 链表结构，特点：保证在遍历时，可以按照添加的顺序遍历，原因：在HashMap的基础上，添加了一对指针，指向前一个后一个
 * 对于频繁的遍历， 这个效率要高
 * TreeMap   保证按照添加的key value 键值对排序。实现按照key的排序遍历：按照key的自然排序和自定义排序
 * 底层使用红黑树。。。。
 * HashTable   ： 较为古老的 线程安全的，效率低
 * properties  ：常用来处理配置文件，key和value都是String类型
 */

import java.util.*;

/**
 * key 不能重复， value可以重复，但是是无序的  如果key是自己定义的类，必须重写 hashCode和equals方法。因为要不重复，其实就是Set
 */

/**
 * JDK7  实现方式
 * 实例化后，底层创建一个长度时16的数组： Entry[] table
 * hashMap.put("key1", "value1");
 * 首先，调用key1所在的hashCode()方法，计算hash值，并经过某种算法后，得到Entry数组里的存放位置
 * 如果这个位置为空，那么可以放  key1-value1添加成功
 * 如果此位置上不空，表明此位置就有一个或者多个，多个则是链表存放 那么 比较当前kye1和已经存放的hash值
 * 如果key1的hash值于已经已经存在的hash值不相同，则添加成功
 * 如果和某一个已经存在的（key2-value2）hash值相同了。继续比较equals方法：调用key1所在类的equals()比较
 * 如果equals()返回false 表明是不一样的，添加成功
 * 如果equals()返回true时，则吧value1的值替换成和key1的值相同的那个,此时 put()就是修改的功能了
 * 比如key1和key2的hashCode和equals都相同了，那么key2的值就变成了key1，相当于js的变量重新赋值
 * <p>
 * 扩容问题
 * 默认扩容方式：扩容为原来容量的2倍，将原有数据复制过来
 */
public class MapTest1 {
    public static void main(String[] args) {
        HashMap hashMap = new HashMap();
//        添加
        hashMap.put("key1", "value1");
        hashMap.put("key2", "value2");
        hashMap.put("key3", "value3");
        hashMap.put("key4", "value4");
//        这里其实就是修改了
        hashMap.put("key1", "value5");
        System.out.println(hashMap);
        HashMap hashMap1 = new HashMap();
        hashMap1.put(123, 456);
        hashMap1.put("ee", 456);
//        加入一个hasMap
        hashMap.putAll(hashMap1);
        System.out.println(hashMap);
//        remove(Object key) 根据key 移除，如果没有，返回null
        hashMap.remove("ee");
        System.out.println(hashMap);
//        clear()  清空map  长度为0  hashMap1.size()=> 0
//        Object get(Object key)  根据key查询 ，没有返回null
        System.out.println(hashMap.get("key11"));
//        boolean containsKey(Object key) ：是否包含指定key
        System.out.println(hashMap.containsKey("key1"));
//        boolean containsValue(Object key) ：是否包含指定value
        System.out.println(hashMap.containsValue("key1"));
//        int size() 返回长度
//        boolean isEmpty()是否为空
        System.out.println(hashMap.isEmpty());
//        boolean equals(Object obj) ：是否和obj相等
        System.out.println(hashMap1.equals(hashMap));


//        遍历：没有迭代器！！！！ 由于key是set，那么可以根据set来遍历，value是collection，也可以遍历
//        Set keySet() ：返回所有key构成的Set集合
        System.out.println("**********  Set keySet()  ******************");
        Set keySet = hashMap.keySet();
        Iterator iterator = keySet.iterator();
        while (iterator.hasNext()) {
            System.out.println(iterator.next());
        }

        System.out.println("**********  Collection values()  ******************");
//        Collection values()  返回所有values构成的Collection
        Collection values = hashMap.values();
        Iterator iterator1 = values.iterator();
        while (iterator1.hasNext()) {
            System.out.println(iterator1.next());
        }

        System.out.println("********** Set entrySet() ******************");
//        Set entrySet()  返回所有key-value构成的Set集合
        Set set = hashMap.entrySet();
        Iterator iterator2 = set.iterator();
        while (iterator2.hasNext()) {
//            Object entry = iterator.next();
            Map.Entry entry = (Map.Entry) iterator2.next();
            System.out.println(entry.getKey() + " ===> " + entry.getValue());

        }
        System.out.println("********** Set entrySet() 方式2  ******************");
        Set keySet1 = hashMap.keySet();
        Iterator iterator3 = keySet.iterator();
        while (iterator3.hasNext()) {
            Object key = iterator3.next();
            Object value = hashMap.get(key);
            System.out.println(key + " ----> " + value);
        }

    }
}
